// app/controller/inventory_controller.js
'use strict';

const Controller = require('egg').Controller;

class InventoryController extends Controller {
  // 获取产品列表
  async getProducts() {
    const { ctx } = this;
    const { page = 1, limit = 20, name, category, brand, status } = ctx.query;
    
    try {
      // 构建查询条件
      const where = {};
      
      // 添加组织过滤条件
      if (ctx.state.organizationId) {
        where.organizationId = ctx.state.organizationId;
      }
      
      if (name && name.trim() !== '') {
        where.name = { [ctx.app.Sequelize.Op.like]: `%${name.trim()}%` };
      }
      if (category && category.trim() !== '') {
        where.categoryId = category;
      }
      if (brand && brand.trim() !== '') {
        where.brandId = brand;
      }
      if (status !== undefined && status.trim() !== '') {
        where.status = status;
      }

      // 分页查询
      const offset = (parseInt(page) - 1) * parseInt(limit);
      const { rows, count } = await ctx.model.ProductModel.findAndCountAll({
        where,
        order: [['createdAt', 'DESC']],
        limit: parseInt(limit),
        offset,
        include: [
          {
            model: ctx.model.ProductCategoryModel,
            as: 'category',
            attributes: ['id', 'name']
          },
          {
            model: ctx.model.BrandModel,
            as: 'brand',
            attributes: ['id', 'name']
          }
        ]
      });

      ctx.page(rows, count, parseInt(page), parseInt(limit));
    } catch (error) {
      ctx.logger.error('获取产品列表失败:', error);
      ctx.error(`获取产品列表失败: ${error.message}`);
    }
  }

  // 获取产品详情
  async getProduct() {
    const { ctx } = this;
    const { id } = ctx.params;

    try {
      const product = await ctx.model.ProductModel.findByPk(id, {
        include: [
          {
            model: ctx.model.ProductCategoryModel,
            as: 'category',
            attributes: ['name']
          },
          {
            model: ctx.model.BrandModel,
            as: 'brand',
            attributes: ['name']
          }
        ]
      });
      
      if (!product) {
        ctx.error('产品不存在', 404);
        return;
      }

      // 处理返回数据，添加类目名称和品牌名称
      const productData = product.toJSON();
      if (productData.category) {
        productData.categoryName = productData.category.name;
        delete productData.category;
      } else {
        productData.categoryName = null;
      }
      if (productData.brand) {
        productData.brandName = productData.brand.name;
        delete productData.brand;
      } else {
        productData.brandName = null;
      }

      ctx.success(productData);
    } catch (error) {
      ctx.logger.error('获取产品详情失败:', error);
      ctx.error(`获取产品详情失败: ${error.message}`);
    }
  }

  // 创建产品
  async createProduct() {
    const { ctx } = this;
    const productData = ctx.request.body;
    
    try {
      // 设置组织ID
      if (ctx.state.organizationId) {
        productData.organizationId = ctx.state.organizationId;
      } else {
        productData.organizationId = 1; // 默认组织ID
      }
      
      // 调用服务层方法
      const result = await ctx.service.inventoryService.createProduct(productData);
      
      ctx.success(result, '产品创建成功');
    } catch (error) {
      ctx.logger.error('创建产品失败:', error);
      ctx.error(`创建产品失败: ${error.message}`);
    }
  }

  // 更新产品
  async updateProduct() {
    const { ctx } = this;
    const { id } = ctx.params;
    const updateData = ctx.request.body;

    try {
      const product = await ctx.model.ProductModel.findByPk(id);
      
      if (!product) {
        ctx.error('产品不存在', 404);
        return;
      }

      // 如果更新SKU，验证唯一性
      if (updateData.sku && updateData.sku !== product.sku) {
        const existingProduct = await ctx.model.ProductModel.findOne({
          where: { sku: updateData.sku }
        });

        if (existingProduct) {
          ctx.error('SKU已存在', 400);
          return;
        }
      }

      // 过滤和处理更新数据
      const filteredData = {};
      
      // 只允许更新特定字段
      const allowedFields = [
        'sku', 'name', 'specification', 'unit', 
        'categoryId', 'brandId', 'description', 
        'stock', 'minStock', 'salePrice', 'costPrice', 'status'
      ];
      
      for (const field of allowedFields) {
        if (field in updateData) {
          // 特殊处理categoryId字段，如果是一个数组，取第一个元素
          if (field === 'categoryId' && Array.isArray(updateData[field])) {
            filteredData[field] = updateData[field][0] || null;
          } 
          // 特殊处理brandId字段，如果是一个数组，取第一个元素
          else if (field === 'brandId' && Array.isArray(updateData[field])) {
            filteredData[field] = updateData[field][0] || null;
          }
          else {
            filteredData[field] = updateData[field];
          }
        }
      }

      // 更新产品
      await product.update(filteredData);
      
      ctx.success(product, '产品更新成功');
    } catch (error) {
      ctx.logger.error('更新产品失败:', error);
      ctx.error(`更新产品失败: ${error.message}`);
    }
  }

  // 删除产品
  async deleteProduct() {
    const { ctx } = this;
    const { id } = ctx.params;

    try {
      const product = await ctx.model.ProductModel.findByPk(id);
      
      if (!product) {
        ctx.error('产品不存在', 404);
        return;
      }

      // 删除产品
      await product.destroy();
      
      ctx.success(null, '产品删除成功');
    } catch (error) {
      ctx.logger.error('删除产品失败:', error);
      ctx.error(`删除产品失败: ${error.message}`);
    }
  }

  // 批量删除产品
  async batchDeleteProducts() {
    const { ctx } = this;
    const { ids } = ctx.request.body;

    try {
      // 删除多个产品
      await ctx.model.ProductModel.destroy({
        where: {
          id: {
            [ctx.app.Sequelize.Op.in]: ids
          }
        }
      });
      
      ctx.success(null, `成功删除 ${ids.length} 个产品`);
    } catch (error) {
      ctx.logger.error('批量删除产品失败:', error);
      ctx.error(`批量删除产品失败: ${error.message}`);
    }
  }

  // 批量更新产品状态
  async batchUpdateProductStatus() {
    const { ctx } = this;
    const { ids, status } = ctx.request.body;

    try {
      // 参数验证
      if (!ids || !Array.isArray(ids) || ids.length === 0) {
        ctx.error('产品ID列表不能为空', 400);
        return;
      }

      if (!status) {
        ctx.error('产品状态不能为空', 400);
        return;
      }

      // 验证状态值是否合法
      const validStatuses = ['active', 'inactive', 'outofstock'];
      if (!validStatuses.includes(status)) {
        ctx.error('产品状态值不合法', 400);
        return;
      }

      // 批量更新产品状态
      const result = await ctx.model.ProductModel.update(
        { status: status },
        { where: { id: ids } }
      );

      ctx.success({
        updatedCount: result[0]
      }, `成功为${result[0]}个产品设置状态`);
    } catch (error) {
      ctx.logger.error('批量更新产品状态失败:', error);
      ctx.error(`批量更新产品状态失败: ${error.message}`);
    }
  }

  // 复制产品
  async cloneProduct() {
    const { ctx } = this;
    const { id } = ctx.params;

    try {
      // 获取原始产品
      const originalProduct = await ctx.model.ProductModel.findByPk(id);
      
      if (!originalProduct) {
        ctx.error('产品不存在', 404);
        return;
      }

      // 创建新产品数据，排除ID和时间戳字段
      const productData = originalProduct.toJSON();
      delete productData.id;
      delete productData.createdAt;
      delete productData.updatedAt;
      
      // 修改SKU以确保唯一性
      const originalSku = productData.sku;
      const skuSuffix = '-copy';
      let newSku = originalSku + skuSuffix;
      
      // 检查新SKU是否已存在，如果存在则添加数字后缀
      let skuExists = await ctx.model.ProductModel.findOne({
        where: { sku: newSku }
      });
      
      let suffixCounter = 1;
      while (skuExists) {
        newSku = originalSku + skuSuffix + suffixCounter;
        skuExists = await ctx.model.ProductModel.findOne({
          where: { sku: newSku }
        });
        suffixCounter++;
      }
      
      productData.sku = newSku;
      
      // 设置组织ID
      if (ctx.state.organizationId) {
        productData.organizationId = ctx.state.organizationId;
      } else {
        productData.organizationId = 1; // 默认组织ID
      }
      
      // 创建新产品
      const newProduct = await ctx.model.ProductModel.create(productData);
      
      ctx.success(newProduct, '产品复制成功');
    } catch (error) {
      ctx.logger.error('复制产品失败:', error);
      ctx.error(`复制产品失败: ${error.message}`);
    }
  }

  // 导入产品
  async importProducts() {
    const { ctx } = this;
    
    try {
      // 获取上传的文件
      const stream = await ctx.getFileStream();
      
      // 检查文件类型
      const filename = stream.filename.toLowerCase();
      if (!filename.endsWith('.xlsx') && !filename.endsWith('.csv')) {
        ctx.error('只支持.xlsx或.csv格式的文件', 400);
        return;
      }
      
      // 解析文件内容
      const XLSX = require('xlsx');
      const fs = require('fs');
      const path = require('path');
      
      // 保存上传的文件到临时位置
      const tempFilePath = path.join(__dirname, '../../temp', Date.now() + '_' + stream.filename);
      
      // 确保临时目录存在
      const tempDir = path.dirname(tempFilePath);
      if (!fs.existsSync(tempDir)) {
        fs.mkdirSync(tempDir, { recursive: true });
      }
      
      // 保存文件
      const writeStream = fs.createWriteStream(tempFilePath);
      stream.pipe(writeStream);
      
      // 等待文件保存完成
      await new Promise((resolve, reject) => {
        writeStream.on('finish', resolve);
        writeStream.on('error', reject);
      });
      
      // 读取并解析Excel文件
      const workbook = XLSX.readFile(tempFilePath);
      const sheetName = workbook.SheetNames[0];
      const worksheet = workbook.Sheets[sheetName];
      
      // 转换为JSON数据
      const jsonData = XLSX.utils.sheet_to_json(worksheet);
      
      // 验证并处理数据
      const validProducts = [];
      const errors = [];
      
      for (let i = 0; i < jsonData.length; i++) {
        const row = jsonData[i];
        const rowIndex = i + 2; // +2 because header is row 1, and Excel is 1-indexed
        
        try {
          // 验证必填字段
          if (!row['SKU'] || !row['产品名称']) {
            errors.push(`第${rowIndex}行: SKU和产品名称为必填字段`);
            continue;
          }
          
          // 验证SKU唯一性
          const existingProduct = await ctx.model.ProductModel.findOne({
            where: { sku: row['SKU'] }
          });
          
          if (existingProduct) {
            errors.push(`第${rowIndex}行: SKU ${row['SKU']} 已存在`);
            continue;
          }
          
          // 构造产品数据
          const productData = {
            sku: row['SKU'],
            name: row['产品名称'],
            specification: row['规格'] || '',
            unit: row['单位'] || '',
            categoryId: row['类目ID'] ? parseInt(row['类目ID']) : null,
            brandId: row['品牌ID'] ? parseInt(row['品牌ID']) : null,
            description: row['描述'] || '',
            stock: parseInt(row['当前库存']) || 0,
            minStock: parseInt(row['安全库存']) || 0,
            salePrice: parseFloat(row['售价']) || 0,
            costPrice: parseFloat(row['成本价']) || 0,
            status: row['状态'] || 'active'
          };
          
          validProducts.push(productData);
        } catch (rowError) {
          errors.push(`第${rowIndex}行: 数据格式错误 - ${rowError.message}`);
        }
      }
      
      // 如果有错误，返回错误信息
      if (errors.length > 0) {
        // 删除临时文件
        if (fs.existsSync(tempFilePath)) {
          fs.unlinkSync(tempFilePath);
        }
        
        ctx.error(`导入失败: \n${errors.join('\n')}`, 400);
        return;
      }
      
      // 批量插入产品数据
      if (validProducts.length > 0) {
        await ctx.model.ProductModel.bulkCreate(validProducts);
      }
      
      // 删除临时文件
      if (fs.existsSync(tempFilePath)) {
        fs.unlinkSync(tempFilePath);
      }
      
      ctx.success({
        importedCount: validProducts.length,
        errorCount: errors.length
      }, `成功导入${validProducts.length}个产品`);
    } catch (error) {
      ctx.logger.error('导入产品失败:', error);
      ctx.error(`导入产品失败: ${error.message}`);
    }
  }

  // 导出产品
  async exportProducts() {
    const { ctx } = this;
    
    try {
      // 这里应该生成导出文件
      // 暂时返回模拟成功响应
      ctx.success(null, '产品导出成功');
    } catch (error) {
      ctx.logger.error('导出产品失败:', error);
      ctx.error(`导出产品失败: ${error.message}`);
    }
  }

  // 获取导入模板
  async getImportTemplate() {
    const { ctx } = this;
    
    try {
      const XLSX = require('xlsx');
      
      // 创建工作簿
      const workbook = XLSX.utils.book_new();
      
      // 创建模板数据
      const templateData = [
        {
          'SKU': '示例SKU001',
          '产品名称': '示例产品名称',
          '规格': '示例规格',
          '单位': '个',
          '类目ID': '',
          '类目名称': '请选择类目',
          '品牌ID': '',
          '品牌名称': '请选择品牌',
          '描述': '示例产品描述',
          '当前库存': 100,
          '安全库存': 20,
          '售价': 10.00,
          '成本价': 5.00,
          '状态': 'active'
        }
      ];
      
      // 创建工作表
      const worksheet = XLSX.utils.json_to_sheet(templateData);
      
      // 添加工作表到工作簿
      XLSX.utils.book_append_sheet(workbook, worksheet, '产品导入模板');
      
      // 设置响应头
      ctx.set('Content-Type', 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet');
      ctx.set('Content-Disposition', 'attachment; filename=product_import_template.xlsx');
      
      // 写入缓冲区并返回
      const buffer = XLSX.write(workbook, { type: 'buffer', bookType: 'xlsx' });
      ctx.body = buffer;
    } catch (error) {
      ctx.logger.error('生成导入模板失败:', error);
      ctx.error(`生成导入模板失败: ${error.message}`);
    }
  }

  // 获取产品统计数据
  async getProductStats() {
    const { ctx } = this;

    try {
      // 添加组织过滤条件
      const where = {};
      if (ctx.state.organizationId) {
        where.organizationId = ctx.state.organizationId;
      }

      // 获取产品总数
      const totalProducts = await ctx.model.ProductModel.count({ where });

      // 获取在售产品数
      const activeProducts = await ctx.model.ProductModel.count({
        where: {
          ...where,
          status: 'active'
        }
      });

      // 获取库存告急产品数（库存小于安全库存）
      const lowStockProducts = await ctx.model.ProductModel.count({
        where: {
          ...where,
          [ctx.app.Sequelize.Op.and]: [
            {
              stock: {
                [ctx.app.Sequelize.Op.lt]: ctx.app.Sequelize.col('min_stock')
              }
            },
            {
              minStock: {
                [ctx.app.Sequelize.Op.gt]: 0
              }
            }
          ]
        }
      });

      // 获取新品数量（最近30天创建的产品）
      const thirtyDaysAgo = new Date();
      thirtyDaysAgo.setDate(thirtyDaysAgo.getDate() - 30);

      const newProducts = await ctx.model.ProductModel.count({
        where: {
          ...where,
          createdAt: {
            [ctx.app.Sequelize.Op.gte]: thirtyDaysAgo
          }
        }
      });

      // 计算趋势数据（与上个月相比）
      const sixtyDaysAgo = new Date();
      sixtyDaysAgo.setDate(sixtyDaysAgo.getDate() - 60);

      // 上个月的产品总数
      const lastMonthTotal = await ctx.model.ProductModel.count({
        where: {
          ...where,
          createdAt: {
            [ctx.app.Sequelize.Op.gte]: sixtyDaysAgo,
            [ctx.app.Sequelize.Op.lt]: thirtyDaysAgo
          }
        }
      });

      // 上个月的在售产品数
      const lastMonthActive = await ctx.model.ProductModel.count({
        where: {
          ...where,
          status: 'active',
          createdAt: {
            [ctx.app.Sequelize.Op.gte]: sixtyDaysAgo,
            [ctx.app.Sequelize.Op.lt]: thirtyDaysAgo
          }
        }
      });

      // 上个月的库存告急产品数
      const lastMonthLowStock = await ctx.model.ProductModel.count({
        where: {
          ...where,
          [ctx.app.Sequelize.Op.and]: [
            {
              stock: {
                [ctx.app.Sequelize.Op.lt]: ctx.app.Sequelize.col('min_stock')
              }
            },
            {
              minStock: {
                [ctx.app.Sequelize.Op.gt]: 0
              }
            }
          ],
          createdAt: {
            [ctx.app.Sequelize.Op.gte]: sixtyDaysAgo,
            [ctx.app.Sequelize.Op.lt]: thirtyDaysAgo
          }
        }
      });

      // 上个月的新品数
      const lastMonthNew = await ctx.model.ProductModel.count({
        where: {
          ...where,
          createdAt: {
            [ctx.app.Sequelize.Op.gte]: sixtyDaysAgo,
            [ctx.app.Sequelize.Op.lt]: thirtyDaysAgo
          }
        }
      });

      // 计算趋势百分比
      const productTrend = lastMonthTotal > 0 ? 
        ((totalProducts - lastMonthTotal) / lastMonthTotal * 100) : 0;
      const activeTrend = lastMonthActive > 0 ? 
        ((activeProducts - lastMonthActive) / lastMonthActive * 100) : 0;
      const lowStockTrend = lastMonthLowStock > 0 ? 
        ((lowStockProducts - lastMonthLowStock) / lastMonthLowStock * 100) : 0;
      const newProductTrend = lastMonthNew > 0 ? 
        ((newProducts - lastMonthNew) / lastMonthNew * 100) : 0;

      const stats = {
        totalProducts,
        activeProducts,
        lowStockProducts,
        newProducts,
        productTrend: parseFloat(productTrend.toFixed(1)),
        activeTrend: parseFloat(activeTrend.toFixed(1)),
        lowStockTrend: parseFloat(lowStockTrend.toFixed(1)),
        newProductTrend: parseFloat(newProductTrend.toFixed(1))
      };

      ctx.success(stats);
    } catch (error) {
      ctx.logger.error('获取产品统计数据失败:', error);
      ctx.error(`获取产品统计数据失败: ${error.message}`);
    }
  }

  // 库存调整
  async adjustInventory() {
    const { ctx } = this;
    const { productId, adjustType, adjustAmount, reason, remark } = ctx.request.body;

    try {
      // 参数验证
      if (!productId) {
        ctx.error('产品ID不能为空', 400);
        return;
      }

      if (!adjustType || !['increase', 'decrease', 'set'].includes(adjustType)) {
        ctx.error('调整类型不合法', 400);
        return;
      }

      if (adjustType !== 'set' && (!adjustAmount || adjustAmount <= 0)) {
        ctx.error('调整数量必须大于0', 400);
        return;
      }

      // 获取产品信息
      const product = await ctx.model.ProductModel.findByPk(productId);
      if (!product) {
        ctx.error('产品不存在', 404);
        return;
      }

      // 计算调整后的库存
      let newStock = product.stock;
      let adjustQuantity = 0;

      switch (adjustType) {
        case 'increase':
          newStock = product.stock + adjustAmount;
          adjustQuantity = adjustAmount;
          break;
        case 'decrease':
          if (product.stock < adjustAmount) {
            ctx.error('库存不足，无法减少', 400);
            return;
          }
          newStock = product.stock - adjustAmount;
          adjustQuantity = -adjustAmount;
          break;
        case 'set':
          newStock = adjustAmount;
          adjustQuantity = adjustAmount - product.stock;
          break;
      }

      // 开始事务处理
      const transaction = await ctx.app.Sequelize.transaction();

      try {
        // 更新产品库存
        await product.update({ stock: newStock }, { transaction });

        // 记录库存调整历史
        const adjustmentData = {
          organizationId: ctx.state.organizationId || 1,
          productId: product.id,
          sku: product.sku,
          productName: product.name,
          beforeStock: product.stock,
          afterStock: newStock,
          adjustQuantity: adjustQuantity,
          adjustType: adjustType,
          reason: reason || '',
          remark: remark || '',
          operatorId: ctx.state.user.id,
          operatorName: ctx.state.user.name
        };

        const adjustment = await ctx.model.InventoryAdjustmentModel.create(adjustmentData, { transaction });

        // 提交事务
        await transaction.commit();

        ctx.success({
          product: product,
          adjustment: adjustment
        }, '库存调整成功');
      } catch (error) {
        // 回滚事务
        await transaction.rollback();
        throw error;
      }
    } catch (error) {
      ctx.logger.error('库存调整失败:', error);
      ctx.error(`库存调整失败: ${error.message}`);
    }
  }

  // 获取库存调整记录
  async getInventoryAdjustments() {
    const { ctx } = this;
    const { productId, page = 1, limit = 20 } = ctx.query;

    try {
      // 构建查询条件
      const where = {};

      // 添加组织过滤条件
      if (ctx.state.organizationId) {
        where.organizationId = ctx.state.organizationId;
      }

      // 如果指定了产品ID，则只查询该产品的调整记录
      if (productId) {
        where.productId = productId;
      }

      // 分页查询
      const offset = (parseInt(page) - 1) * parseInt(limit);
      const { rows, count } = await ctx.model.InventoryAdjustmentModel.findAndCountAll({
        where,
        order: [['createdAt', 'DESC']],
        limit: parseInt(limit),
        offset
      });

      ctx.page(rows, count, parseInt(page), parseInt(limit));
    } catch (error) {
      ctx.logger.error('获取库存调整记录失败:', error);
      ctx.error(`获取库存调整记录失败: ${error.message}`);
    }
  }
}

module.exports = InventoryController;